package io.cici.cc.mybatis.plus.core;

import io.cici.cc.mybatis.lite.builder.Builder;
import io.cici.cc.mybatis.lite.builder.MapperBuilder;
import io.cici.cc.mybatis.lite.builder.xml.XmlMapperBuilder;
import io.cici.cc.mybatis.lite.session.Configuration;
import io.cici.cc.mybatis.plus.core.toolkit.GlobalConfigUtils;
import io.cici.cc.mybatis.plus.core.toolkit.StringPool;

import java.io.InputStream;
import java.lang.reflect.Method;

public class MybatisMapperAnnotationBuilder extends Builder {


    private final Configuration configuration;
    private final MapperBuilder mapperBuilder;
    private final Class<?> type;

    public MybatisMapperAnnotationBuilder(Configuration configuration, Class<?> type) {
        super(configuration);
        String resource = type.getName().replace(StringPool.DOT, StringPool.SLASH) + ".java (best guess)";
        this.mapperBuilder = new MapperBuilder(configuration, resource);
        this.configuration = configuration;
        this.type = type;
    }


    public void parse() {
        String resource = type.toString();
        if (!configuration.isResourceLoaded(resource)) {
            loadXmlResource();
            configuration.addLoadedResource(resource);
            String mapperName = type.getName();
            mapperBuilder.setNamespace(mapperName);

            for (Method method : type.getMethods()) {
                if (!canHaveStatement(method)) {
                    continue;
                }


            }
            // TODO 注入 CURD 动态 SQL , 放在在最后, because 可能会有人会用注解重写sql
            // https://github.com/baomidou/mybatis-plus/issues/3038
            if (GlobalConfigUtils.isSupperMapperChildren(configuration, type)) {
                parserInjector();
            }
        }

    }

    void parserInjector() {
        GlobalConfigUtils.getSqlInjector(configuration).inspectInject(mapperBuilder, type);
    }

    private boolean canHaveStatement(Method method) {
        // issue #237
        return !method.isBridge() && !method.isDefault();
    }

    private void loadXmlResource() {
        // Spring may not know the real resource name so we check a flag
        // to prevent loading again a resource twice
        // this flag is set at XMLMapperBuilder#bindMapperForNamespace
        if (!configuration.isResourceLoaded("namespace:" + type.getName())) {
            String xmlResource = type.getName().replace(StringPool.DOT, StringPool.SLASH) + ".xml";
            // #1347
            InputStream inputStream = type.getResourceAsStream(StringPool.SLASH + xmlResource);

            if (inputStream != null) {
                XmlMapperBuilder xmlParser = new XmlMapperBuilder(inputStream, mapperBuilder.getConfiguration(),
                        xmlResource, configuration.getSqlIdToNodeMap(), type.getName());
                xmlParser.parse();
            }
        }
    }


}
